import {
  BleConnection
} from './inner_ble_connection.js';

import {
  executeBasicProcess
} from './base_process.js'

/**
 * @param {*} otaTask {rawData,address}
 */
function startOta(deviceId, otaTask, stateCallback, onFinish) {
  execute(deviceId, false, [otaTask], stateCallback, onFinish)
}

/**
 * @param {*} OtaTasks //[{rawData,address},{}..]
 */
function startFastOta(deviceId, otaTasks, stateCallback, onFinish) {
  execute(deviceId, true, otaTasks, stateCallback, onFinish)
}

function delay(millis) {
  return new Promise((resolve, reject) => {
    setTimeout(function(){
      resolve('')
    },millis)
  })
}

async function execute(deviceId, fastMode, otaTasks, stateCallback, onFinish) {
  try {
    const bleConnectioin = new BleConnection()
    const devices = await getConnectedDevices(deviceId)
    if (devices && devices.length > 0) {
      //已连接，发现服务
      await bleConnectioin.setup(deviceId)
    } else {
      await bleConnectioin.connect(deviceId)
    }

    let bx_ota_service_uuid = "00002600-0000-1000-8000-00805F9B34FB"
    let bx_ota_ctrl_uuid = "00007000-0000-1000-8000-00805F9B34FB"

    await bleConnectioin.enableNotification(bx_ota_service_uuid, bx_ota_ctrl_uuid, true)

    await delay(100)

    let mtuSize = 23
    if (fastMode) {
      try {
        let res = await bleConnectioin.requestMtu(512)
        mtuSize = res.mtu
      } catch (ignore) {
        console.log(ignore)
      }
    }
    if (mtuSize > 251) {
      mtuSize = 251
    }
    console.log("mtu " + mtuSize)
    let state = {
      index: 0,
      startTime: 0,
      endTime: 0,
      progress: 0,
      errorMessage: null
    }
    for (let i = 0; i < otaTasks.length; i++) {
      try {
        state.index = i
        state.startTime = new Date().getTime()
        stateCallback(state)
        await executeBasicProcess(bleConnectioin, otaTasks[i].rawData, otaTasks[i].address, mtuSize, (progress) => {
          state.progress = progress
          stateCallback(state)
        })
        if (fastMode) {
          let appleyCmd = new Uint8Array([0x0A]).buffer
          await bleConnectioin.writeBuffer(bx_ota_service_uuid, bx_ota_ctrl_uuid, true, appleyCmd)
        }
        state.endTime = new Date().getTime()
        stateCallback(state)
      } catch (e) {
        state.endTime = new Date().getTime()
        state.errorMessage = e
        stateCallback(state)
      }
    }
    if (fastMode) {
      let rebootCmd = new Uint8Array([0x0B]).buffer
      console.log(rebootCmd)
      bleConnectioin.writeBuffer(bx_ota_service_uuid, bx_ota_ctrl_uuid, true, rebootCmd)
    }
    onFinish({
      result: true
    })
  } catch (err) {
    console.error(err)
    onFinish({
      result: false,
      error: err
    })
  }
}

/**
 * 
 * return
 * success [{"name","deviceId"}]
 * failed {"code"}
 */
function getConnectedDevices(deviceId) {
  return new Promise((resolve, reject) => {
    wx.getConnectedBluetoothDevices({
      services: ['2600'],
      success(res) {
        resolve(res)
      },
      fail(err) {
        console.error(err)
        resolve([])
      }
    })
  })
}

const _startOta = startOta
export {
  _startOta as startOta
}
const _startFastOta = startFastOta
export {
  _startFastOta as startFastOta
}